/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#ifndef INCLUDE_BASIC_VEC
#define INCLUDE_BASIC_VEC

#include "basic_def.h"

#define DEF_VC_CPU 0

#define M_PI 3.1415926535897932384626433832795


#undef max
#undef min


typedef struct _ui32 {	
	uint32 x, y;		
}ui2_32, uvec2;			

typedef struct _i32_2 { 
	int32 x, y;         
}ivec2;


typedef struct _Vec3 {  
	float32 x, y, z;    
} vec3;	

typedef struct {				
	float32 x; float32 y;		
}vec2;		


typedef struct _Vec4 {							
	float32 x; float32 y; float32 z; float32 w;	
}vec4;	

typedef struct _i32_3 {
	int32 x, y, z;
}ivec3;

typedef struct {
	ivec3 m[2];
}imat23;

typedef struct _ui3_32 {			
	uint32 x; uint32 y; uint32 z;	
}uvec3;

typedef struct _ivec4_32 {
	int32 x, y, z, w;
}ivec4;

typedef struct _ui4_32 {					
	uint32 x; uint32 y; uint32 z; uint32 w;	
}uvec4;

typedef struct _ui4_64 {
	uint64 x, y, z, w;
}uvec4_64;

typedef struct {
	int8 x, y;
}bvec2;
typedef struct {
	uint8 x, y;
}ubvec2;
typedef struct {
	uint8 x, y, z;
}ubvec3;

typedef struct {
	int8 x, y, z, w;
}bvec4;

typedef struct _uivec4_8 {
	uint8 x; uint8 y; uint8 z; uint8 w;
}ub4, ubvec4;

//typedef struct _ui16 {
//	uint16 x; uint16 y;
//}ui2_16, suvec2;
//typedef struct _i2_16 {
//	int16 x; int16 y;
//}i2_16, svec2;

typedef struct {
	uint8 x; uint8 y; uint8 z; uint8 w;
}uvec4_8;

typedef struct _ui32_4 {
	uint32 x; uint32 y; uint32 z; uint32 w;
}ui32_4;

typedef struct _i3_16 {
	int16 x, y, z;
}svec3;
typedef struct _i4_16 {
	int16 x, y, z, w;
}svec4;
typedef struct _ui4_16 {
	uint16 x, y, z, w;
}usvec4;



//========================= 颜色数据类型 ===========================
typedef struct {
	uint8 r;
	uint8 g;
	uint8 b;
}S_RGB8UI;

typedef struct {
	uint8 r;
	uint8 g;
	uint8 b;
	uint8 a;
}S_RGBA8UI;

typedef struct _Color {
	float32 r, g, b, a;
} color;



//========================= 范围数据类型 ===========================
typedef struct {
	vec3   pos;
	vec3   size;
}S_Cube;

typedef struct {
	vec3   min;
	vec3   max;
}S_Bounding;

typedef struct {
	vec2   min;
	vec2   max;
}S_Bounding2;


//========================= 顶点数据类型 ===========================
struct S_VC {
	vec3	vert;
	uint32	color;
};

struct S_VNT1 {
	vec3 vert;
	vec3 normal;
	vec2 UV;
};

struct S_VNT2 {
	vec3 vert;
	vec3 normal;
	vec2 UV1;
	vec2 UV2;
};

struct S_VN {
	vec3 vert;
	vec3 normal;
};

struct S_VNTC {
	vec3	vert;
	vec3	normal;
	vec3	uv_color;
};




Inline vec2 operator+(const vec2& a, const float32 b) {
	return { a.x + b, a.y + b };
};
Inline vec2 operator+(const vec2& a, const vec2& b) {
	return { a.x + b.x, a.y + b.y };
};


Inline vec2 operator*(const vec2& a, const float32 b) {
	return { a.x * b, a.y * b };
};
Inline vec2 operator*(const vec2& a, const uvec2& b) {
	return {a.x * b.x, a.y * b.y};
};
Inline vec2 operator*(const vec2& a, const vec2& b) {
	return { a.x * b.x, a.y * b.y };
};


Inline vec2 operator-(const vec2& a, const vec2& b) {
	return { a.x - b.x, a.y - b.y };
};
Inline vec2 operator-(const vec2& a, const ivec2& b) {
	return { a.x - b.x, a.y - b.y };
};
Inline vec2 operator-(const vec2& a, const float32 b) {
	return { a.x - b, a.y - b };
};

Inline vec2 operator/(const vec2& a, const vec2& b) {
	return { a.x / b.x, a.y / b.y };
};

Inline vec2 operator/(const vec2& a, const float32 b) {
	return { a.x / b, a.y / b };
};

Inline void operator/=(vec2& a, const uvec2& b) {
	a.x /= b.x; a.y /= b.y;
};

Inline vec2 operator/(const vec2& a, const uvec2& b) {
	return { a.x / b.x, a.y / b.y };
};


Inline void operator*=(vec2& a, const float32 b) {
	a.x *= b; a.y *= b;
};


Inline void operator+=(vec2& a, const float32 b) {
	a.x += b; a.y += b;
};
Inline void operator+=(vec2& a, const vec2& b) {
	a.x += b.x; a.y += b.y;
};
Inline void operator-=(vec2& a, const float32& b) {
	a.x -= b; a.y -= b;
};
Inline void operator-=(vec2& a, const vec2& b) {
	a.x -= b.x; a.y -= b.y;
};
Inline vec2 operator*(vec2& a, const vec2& b) {
	return {a.x * b.x, a.y * b.y};
};
Inline void operator*=(vec2& a, const vec2& b) {
	a.x *= b.x; a.y *= b.y;
};
Inline void operator/=(vec2& a, const float32 b) {
	a.x /= b; a.y /= b;
};
Inline void operator/=(vec2& a, const vec2& b) {
	a.x /= b.x; a.y /= b.y;
};

Inline vec2 operator-(const vec2& a) {
	return { -a.x, -a.y };
};

Inline bool operator < (const vec2& a, const vec2& b) {
	return a.x < b.x && a.y < b.y ;
};

Inline bool operator==(const vec2& a, const vec2& b) {
	return a.x == b.x && a.y == b.y;
}
Inline bool operator!=(const vec2& a, const vec2& b) {
	return a.x != b.x || a.y != b.y;
}





Inline bool operator==(const ivec2& a, const ivec2& b) {
	return a.x == b.x && a.y == b.y;
};
Inline bool operator!=(const ivec2& a, const ivec2& b) {
	return a.x != b.x && a.y != b.y;
};



Inline uvec2 operator+(const uvec2& a, const int32 b) {
	return { a.x + b, a.y + b };
};

Inline uvec2 operator+(const uvec2& a, const uint32 b) {
	return { a.x + b, a.y + b };
};

Inline uvec2 operator+(const uvec2& a, const uvec2& b) {
	return { a.x + b.x, a.y + b.y };
};

Inline uvec2 operator-(const uvec2& a, const uvec2& b) {
	return { a.x - b.x, a.y - b.y };
};
Inline uvec2 operator*(const uvec2& a, const uint32& b) {
	return { a.x * b, a.y * b };
};
Inline uvec2 operator*(const uvec2& a, const uvec2& b) {
	return { a.x * b.x, a.y * b.y };
};

Inline uvec2 operator/(const uvec2& a, const uvec2& b) {
	return { a.x / b.x, a.y / b.y };
};

Inline uvec2 operator/(const uvec2& a, const int32& b) {
	return { a.x / b, a.y / b };
};

Inline uvec2 operator/(const uvec2& a, const uint32& b) {
	return { a.x / b, a.y / b };
};

Inline void operator/=(uvec2& a, const uint32& b) {
	a.x /= b; a.y /= b;
};
Inline void operator&=(uvec2& a, const uint32& b) {
	a.x &= b; a.y &= b;
};

Inline void operator+=(uvec2& a, uint32 b) {
	a.x += b; a.y += b;
};
Inline void operator*=(uvec2& a, uint32 b) {
	a.x *= b; a.y *= b;
};

Inline uvec2 operator >> (const uvec2& a, const uint32 b) {
	return { a.x >> b, a.y >> b };
}


//Inline bool operator!=(const vec2& a, const vec2& b) {
//	return a.x != b.x && a.y != b.y;
//}


/****************************************** vec3 *******************************************/

Inline vec3 operator+(const vec3& a, const float32& b) {
	return { a.x + b, a.y + b, a.z + b };
};
Inline vec3 operator+(const vec3& a, const vec3& b) {
	return { a.x + b.x, a.y + b.y, a.z + b.z };
};
Inline vec3 operator+(const vec3& a, const ivec3& b) {
	return { a.x + b.x, a.y + b.y, a.z + b.z };
};

Inline vec3 operator*(const vec3& a, const float32& b) {
	return { a.x * b, a.y * b, a.z * b };
};
Inline vec3 operator*(const vec3& a, const vec3& b) {
	return { a.x * b.x, a.y * b.y, a.z * b.z };
};
Inline vec3 operator*(const vec3& a, const ivec3& b) {
	return { a.x * b.x, a.y * b.y, a.z * b.z };
};
Inline vec3 operator*(const vec3& a, const uvec3& b) {
	return { a.x * b.x, a.y * b.y, a.z * b.z };
};


Inline vec3 operator-(const vec3& a, const float32& b) {
	return { a.x - b, a.y - b, a.z - b };
};
Inline vec3 operator-(const vec3& a, const vec3& b) {
	return { a.x - b.x, a.y - b.y, a.z - b.z };
};
Inline vec3 operator-(const vec3& a, const uvec3& b) {
	return { a.x - b.x, a.y - b.y, a.z - b.z };
};
Inline vec3 operator-(const vec3& a, const ivec3& b) {
	return { a.x - b.x, a.y - b.y, a.z - b.z };
};
Inline vec3 operator-(const float32 a, const vec3& b) {
	return { a - b.x, a - b.y, a - b.z };
};



Inline void operator*=(vec3& a, const vec3& b) {
	a.x *= b.x; a.y *= b.y; a.z *= b.z;
};

Inline void operator*=(vec3& a, const float32& b) {
	a.x *= b; a.y *= b; a.z *= b;
};

Inline vec3 operator/(const vec3& a, const uvec3& b) {
	return { a.x / b.x, a.y / b.y, a.z / b.z };
};
inline vec3 operator/(const vec3& a, const float32& b) {
	return { a.x / b, a.y / b, a.z / b };
};
inline vec3 operator/(const vec3& a, const vec3& b) {
	return { a.x / b.x, a.y / b.y, a.z / b.z };
};


Inline void operator/=(vec3& a, const vec3& b) {
	a.x /= b.x; a.y /= b.y; a.z /= b.z;
};
Inline void operator/=(vec3& a, const uvec3& b) {
	a.x /= b.x; a.y /= b.y; a.z /= b.z;
};
Inline void operator/=(vec3& a, const float32& b) {
	a.x /= b; a.y /= b; a.z /= b;
};

Inline void operator+=(vec3& a, const float32 b) {
	a.x += b; a.y += b; a.z += b;
}
Inline void operator-=(vec3& a, const float32 b) {
	a.x -= b; a.y -= b; a.z -= b;
}

Inline void operator+=(vec3& a, const vec3& b) {
	a.x += b.x; a.y += b.y; a.z += b.z;
}

Inline void operator-=(vec3& a, const vec3& b) {
	a.x -= b.x; a.y -= b.y; a.z -= b.z;
}








Inline ivec3 operator-(ivec3& a) {
	return { -a.x, -a.y, -a.z };
}

Inline vec3 operator+(const ivec3& a, const float32& b) {
	return { (a.x + b), (a.y + b), (a.z + b) };
}
Inline vec3 operator*(const ivec3& a, const float32& b) {
	return { (a.x * b), (a.y * b), (a.z * b) };
}
Inline ivec3 operator+(const ivec3& a, const uvec3& b) {
	return { int32(a.x + b.x), int32(a.y + b.y), int32(a.z + b.z) };
}
Inline ivec3 operator + (const ivec3& a, const ivec3& b) {
	return { a.x + b.x, a.y + b.y, a.z + b.z };
};
Inline ivec3 operator - (const ivec3& a, const ivec3& b) {
	return { a.x - b.x, a.y - b.y, a.z - b.z };
};
Inline void operator+=(ivec3& a, const ivec3& b) {
	a.x += b.x; a.y += b.y; a.z += b.z ;
};
Inline void operator-=(ivec3& a, const ivec3& b) {
	a.x -= b.x; a.y -= b.y; a.z -= b.z;
};


Inline uvec3 operator+(const uvec3& a, const uvec3& b) {
	return { uint32(a.x + b.x), uint32(a.y + b.y), uint32(a.z + b.z) };
}
Inline uvec3 operator+(const uvec3& a, const ivec3& b) {
	return { uint32(a.x + b.x), uint32(a.y + b.y), uint32(a.z + b.z) };
}


Inline uvec3 operator-(const uvec3& a, const float32 b) {
	return { uint32(a.x - b), uint32(a.y - b), uint32(a.z - b) };
};
Inline uvec3 operator-(const uvec3& a, const int32 b) {
	return { uint32(a.x - b), uint32(a.y - b), uint32(a.z - b) };
};
Inline uvec3 operator-(const uvec3& a, const uvec3& b) {
	return { a.x - b.x, a.y - b.y, a.z - b.z };
};
Inline vec3 operator-(const uvec3& a, const vec3& b) {
	return { a.x - b.x, a.y - b.y, a.z - b.z };
};



Inline uvec3 operator*(const uvec3& a, float32 b) {
	return { uint32(a.x * b), uint32(a.y * b), uint32(a.z * b) };
}
Inline uvec3 operator/(const uvec3& a, const uvec3& b) {
	return { uint32(a.x / b.x), uint32(a.y / b.y), uint32(a.z / b.z) };
}
Inline uvec3 operator/(const uvec3& a, const uint32 b) {
	return { uint32(a.x / b), uint32(a.y / b), uint32(a.z / b) };
}
Inline uvec3 operator/(const uvec3& a, const ivec3& b) {
	return { uint32(a.x / b.x), uint32(a.y / b.y), uint32(a.z / b.z) };
}

Inline void operator*=(uvec3& a, const uint32 b) {
	a.x *= b; a.y *= b; a.z *= b;
}
Inline void operator/=(uvec3& a, const uint32 b) {
	a.x /= b; a.y /= b; a.z /= b;
}
Inline uvec3 operator >> (const uvec3& a, const uint32 b) {
	return {a.x >> b, a.y >> b, a.z >> b};
}



Inline vec4 operator*(const vec4& a, const float32 b) {
	return { a.x * b, a.y * b, a.z * b, a.w * b };
};
Inline vec4 operator*(const vec4& a, const int32 b) {
	return { a.x * b, a.y * b, a.z * b, a.w * b };
};
Inline vec4 operator*(const vec4& a, const uint32 b) {
	return { a.x * b, a.y * b, a.z * b, a.w * b };
};
Inline vec4 operator*(const vec4& a, const vec4& b) {
	return { a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w };
};

Inline void operator+=(vec4& a, const vec4& b) {
	a.x += b.x; a.y += b.y; a.z += b.z; a.w += b.w;
}
Inline void operator*=(vec4& a, const float& b) {
	a.x *= b; a.y += b; a.z *= b; a.w *= b;
}
Inline void operator*=(vec4& a, const vec4& b) {
	a.x *= b.x; a.y += b.y; a.z *= b.z; a.w *= b.w;
}


Inline uvec4 operator-(const uvec4& a, const uvec4& b) {
	return { a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w };
};








Inline vec2 vec_3to2(const vec3& vec) {
	return { vec.x, vec.y };
}
Inline vec2 vec_4to2(const vec4& vec) {
	return { vec.x, vec.y };
}

Inline vec2 _Vec2(const float32 vec) {
	return { float32(vec), float32(vec) };
}
Inline vec2 _Vec2(const float32 x, const float32 y) {
	return { float32(x), float32(y) };
}
Inline vec2 _Vec2(const ivec2& vec) {
	return { float32(vec.x), float32(vec.y) };
}
Inline vec2 _Vec2(const uvec2& vec) {
	return { float32(vec.x), float32(vec.y) };
}
Inline vec2 _Vec2(const uvec3& vec) {
	return { float32(vec.x), float32(vec.y) };
}
Inline vec2 _Vec2(const ivec3& vec) {
	return { float32(vec.x), float32(vec.y) };
}
Inline vec2 _Vec2(const ivec4& vec) {
	return { float32(vec.x), float32(vec.y) };
}
Inline vec2 _Vec2(const vec3& vec) {
	return { vec.x, vec.y };
}
Inline vec2 _Vec2(const vec4& vec) {
	return { vec.x, vec.y };
}

Inline uvec2 _uVec2(const uint32 vec) {
	return { vec, vec };
}
Inline uvec2 _uVec2(const vec2& vec) {
	return { uint32(vec.x), uint32(vec.y) };
}
Inline uvec2 _uVec2(const ivec2& vec) {
	return { uint32(vec.x), uint32(vec.y) };
}
Inline uvec2 _uVec2(const uvec3& vec) {
	return { uint32(vec.x), uint32(vec.y) };
}
Inline uvec2 _uVec2(int32 x, int32 y) {
	return { uint32(x), uint32(y) };
}


Inline ivec2 _iVec2(const int32& vec) { return { int32(vec), int32(vec) }; }
Inline ivec2 _iVec2(const vec2& vec) { return { int32(vec.x), int32(vec.y) }; }
Inline ivec2 _iVec2(const uvec2& vec) { return { int32(vec.x), int32(vec.y) }; }

Inline vec3 _Vec3(const float32* a) { return { a[0], a[1], a[2]}; }
//Inline vec3 _Vec3(const float32& a) { return { a, a, a }; }
Inline vec3 _Vec3(const float32 a) { return { a, a, a }; }
Inline vec3 _Vec3(float32 x, float32 y, float32 z) { return { x, y, z }; }
Inline vec3 _Vec3(float32 x, vec2 yz) { return { x, yz.x, yz.y }; }
Inline vec3 _Vec3(vec2 xy, float32 z) { return { xy.x, xy.y, z }; }

Inline vec3 _Vec3(const vec2& vec) { return { vec.x, vec.y, 0 }; }
Inline vec3 _Vec3(const vec3& vec) { return { vec.x, vec.y, vec.z }; }
Inline vec3 _Vec3(const vec4& vec) { return { vec.x, vec.y, vec.z }; }
Inline vec3 _Vec3(const ivec2& vec) { return { float32(vec.x), float32(vec.y), float32(0) }; }
Inline vec3 _Vec3(const ivec3& vec) { return { float32(vec.x), float32(vec.y), float32(vec.z) }; }
Inline vec3 _Vec3(const ivec4& vec) { return { float32(vec.x), float32(vec.y), float32(vec.z) }; }
Inline vec3 _Vec3(const uvec2& vec) { return { float32(vec.x), float32(vec.y), float32(0) }; }
Inline vec3 _Vec3(const uvec3& vec) { return { float32(vec.x), float32(vec.y), float32(vec.z) }; }
Inline vec3 _Vec3(const uvec4& vec) { return { float32(vec.x), float32(vec.y), float32(vec.z) }; }

Inline ivec3 _iVec3(const int8 vec) { return { int32(vec), int32(vec), int32(vec) }; }
Inline ivec3 _iVec3(const int32 vec) { return { int32(vec), int32(vec), int32(vec) }; }
Inline ivec3 _iVec3(const uint32 vec) { return { int32(vec), int32(vec), int32(vec) }; }
Inline ivec3 _iVec3(const float32 vec) { return { int32(vec), int32(vec), int32(vec) }; }
Inline ivec3 _iVec3(const vec2& vec) { return { int32(vec.x), int32(vec.y), 0 }; }
Inline ivec3 _iVec3(const vec3& vec) { return { int32(vec.x), int32(vec.y), int32(vec.z) }; }
Inline ivec3 _iVec3(const vec4& vec) { return { int32(vec.x), int32(vec.y), int32(vec.z) }; }
Inline ivec3 _iVec3(const uvec2& vec) { return { int32(vec.x), int32(vec.y), 0 }; }
Inline ivec3 _iVec3(const uvec3& vec) { return { int32(vec.x), int32(vec.y), int32(vec.z) }; }
Inline ivec3 _iVec3(const uvec4& vec) { return { int32(vec.x), int32(vec.y), int32(vec.z) }; }
Inline ivec3 _iVec3(const float32& x, const float32& y, const float32& z) { return { int32(x), int32(y), int32(z) }; }


Inline uvec3 _uVec3(const int8 vec) { return { uint32(vec), uint32(vec), uint32(vec) }; }
Inline uvec3 _uVec3(const int32 vec) { return { uint32(vec), uint32(vec), uint32(vec) }; }
Inline uvec3 _uVec3(const uint32 vec) { return { uint32(vec), uint32(vec), uint32(vec) }; }
Inline uvec3 _uVec3(const uint32 x, const uint32 y, const uint32 z) { return { x, y, z }; }
Inline uvec3 _uVec3(const uvec2 xy, const uint32 z) { return { xy.x, xy.y, z }; }
Inline uvec3 _uVec3(const float32 vec) { return { uint32(vec), uint32(vec), uint32(vec) }; }
Inline uvec3 _uVec3(const uvec2& vec) { return { uint32(vec.x), uint32(vec.y), 0 }; }
Inline uvec3 _uVec3(const vec3& vec) { return { uint32(vec.x), uint32(vec.y), uint32(vec.z) }; }
Inline uvec3 _uVec3(const ivec2& vec, uint32 a) { return { uint32(vec.x), uint32(vec.y), a }; }
Inline uvec3 _uVec3(const ivec3& vec) { return { uint32(vec.x), uint32(vec.y), uint32(vec.z) }; }


Inline ivec4 _iVec4(const int8 vec) { return { int32(vec), int32(vec), int32(vec), int32(vec) }; }
Inline ivec4 _iVec4(const int32 vec) { return { int32(vec), int32(vec), int32(vec), int32(vec) }; }
Inline ivec4 _iVec4(const uint32 vec) { return { int32(vec), int32(vec), int32(vec), int32(vec) }; }
Inline ivec4 _iVec4(const float32 vec) { return { int32(vec), int32(vec), int32(vec), int32(vec) }; }
Inline ivec4 _iVec4(const vec2& vec) { return { int32(vec.x), int32(vec.y), 0, 0 }; }
Inline ivec4 _iVec4(const vec3& vec) { return { int32(vec.x), int32(vec.y), int32(vec.z), 0 }; }
Inline ivec4 _iVec4(const vec4& vec) { return { int32(vec.x), int32(vec.y), int32(vec.z), 0 }; }
Inline ivec4 _iVec4(const ivec2& vec) { return { int32(vec.x), int32(vec.y), 0, 0 }; }
Inline ivec4 _iVec4(const ivec3& vec) { return { int32(vec.x), int32(vec.y), int32(vec.z), 0 }; }
Inline ivec4 _iVec4(const uvec2& vec) { return { int32(vec.x), int32(vec.y), 0, 0 }; }
Inline ivec4 _iVec4(const uvec3& vec) { return { int32(vec.x), int32(vec.y), int32(vec.z), 0 }; }
Inline ivec4 _iVec4(const uvec4& vec) { return { int32(vec.x), int32(vec.y), int32(vec.z), int32(vec.w) }; }

Inline S_Cube _S_Cube(const float32& vec) { return { {}, {float32(vec), float32(vec), float32(vec)} }; }
Inline S_Cube _S_Cube(const vec3& vec) { return { {}, {float32(vec.x), float32(vec.y), float32(vec.z)} }; }
Inline S_Cube _S_Cube(const vec4& vec) { return { {}, {float32(vec.x), float32(vec.y), float32(vec.z)} }; }
Inline S_Cube _S_Cube(const ivec3& vec) { return { {}, {float32(vec.x), float32(vec.y), float32(vec.z)} }; }


Inline vec3 yzx(const vec3& vec) { return { vec.y, vec.z, vec.x }; }
Inline vec3 zxy(const vec3& vec) { return {vec.z, vec.x, vec.y}; }


Inline vec4 _Vec4(const float32& a) { return { a, a, a, 1 }; }
Inline vec4 _Vec4(const int32& a) { return { float32(a), float32(a), float32(a), 1 }; }
Inline vec4 _Vec4(const vec3& vec, float32 w = 1) { return { vec.x, vec.y, vec.z, w }; }
Inline vec4 _Vec4(const vec4& vec) { return vec; }
Inline vec4 _Vec4(const S_RGBA8UI& vec) { return { float32(vec.r), float32(vec.g), float32(vec.b), float32(vec.a) }; }



Inline uvec2 max(const uvec2& a, const uvec2& b) {
	return { a.x > b.x ? a.x : b.x,   a.y > b.y ? a.y : b.y };
};

Inline vec4 max(const vec4& a, const float& b) {
	return { a.x > b ? a.x : b, a.y > b ? a.y : b, a.z > b ? a.z : b, a.z > b ? a.z : b };
};

Inline uint32 max(const uvec2& a) {
	return a.x > a.y ? a.x : a.y;
};

/*Inline vec3 normalize(const vec3& vec) {
	float len = (float)vec_len(vec) + 1e-7;
	if (len) {
		return { vec.x / len, vec.y / len, vec.z / len };
	}
	else return {};
}*/


Inline bool operator == (const uvec2& a, const uvec2& b) {
	return a.x == b.x && a.y == b.y;
};



Inline bool operator == (const ivec3& a, const ivec3& b) {
	return  a.x == b.x && a.y == b.y && a.z == b.z ;
};

Inline bool operator != (const ivec3& a, const ivec3& b) {
	return  a.x != b.x || a.y != b.y || a.z != b.z;
};

Inline ivec3 operator - (const ivec3& a, const int32 b) {
	return { a.x - b, a.y - b, a.z - b };
};






Inline uvec3 operator+(const uvec3& a, const float32& b) {
	return { uint32(a.x + b), uint32(a.y + b), uint32(a.z + b) };
};

Inline vec3 operator+(const uvec3& a, const vec3& b) {
	return { a.x + b.x, a.y + b.y, a.z + b.z };
};

Inline uvec3 operator+(const uvec3& a, const uint32 b) {
	return { a.x + b, a.y + b, a.z + b };
};

Inline void operator+=(uvec3& a, const float32 b) {
	a.x += uint32(b); a.y += uint32(b); a.z += uint32(b);
};





Inline vec3 operator-(const vec3& a) {
	return {-a.x, -a.y, -a.z};
};








Inline uvec3 vec_Max(const uvec3& v1, const uint32& v2) {
	return { DEF_Max(v1.x, v2), DEF_Max(v1.y, v2), DEF_Max(v1.z, v2) };
}
Inline uvec3 vec_Min(const uvec3& v1, const uint32& v2) {
	return { DEF_Min(v1.x, v2), DEF_Min(v1.y, v2), DEF_Min(v1.z, v2) };
}

Inline uvec3 vec_Min(const uvec3& v1, const uvec3& v2) {
	return { DEF_Min(v1.x, v2.x), DEF_Min(v1.y, v2.y), DEF_Min(v1.z, v2.z) };
}
Inline uvec3 vec_Max(const uvec3& v1, const uvec3& v2) {
	return { DEF_Max(v1.x, v2.x), DEF_Max(v1.y, v2.y), DEF_Max(v1.z, v2.z) };
}

Inline uvec3 vec_Min(const uvec3& v1, const ivec3& v2) {
	return { uint32(DEF_Min(int32(v1.x), v2.x)), uint32(DEF_Min(int32(v1.y), v2.y)), uint32(DEF_Min(int32(v1.z), v2.z)) };
}
Inline uvec3 vec_Max(const uvec3& v1, const ivec3& v2) {
	return { uint32(DEF_Max(int32(v1.x), v2.x)), uint32(DEF_Max(int32(v1.y), v2.y)), uint32(DEF_Max(int32(v1.z), v2.z)) };
}




Inline float32 clamp(float32 x, float32 minVal, float32 maxVal) {
	return DEF_Min(DEF_Max(x, minVal), maxVal);
}
Inline ivec3 clamp(ivec3 x, ivec3 minVal, ivec3 maxVal) {
	return { DEF_Min(DEF_Max(x.x, minVal.x), maxVal.x), DEF_Min(DEF_Max(x.y, minVal.y), maxVal.y), DEF_Min(DEF_Max(x.z, minVal.z), maxVal.z) };
}
Inline uvec3 clamp(uvec3 x, uvec3 minVal, uvec3 maxVal) {
	return { DEF_Min(DEF_Max(x.x, minVal.x), maxVal.x), DEF_Min(DEF_Max(x.y, minVal.y), maxVal.y), DEF_Min(DEF_Max(x.z, minVal.z), maxVal.z) };
}


Inline float32 mix(const float32& x, const float32& y, const float a) {
	return x * (1.0f - a) + y * a;
}

Inline vec2 mix(const vec2& x, const vec2& y, const float32 a) {
	return { x.x * (1.0f - a) + y.x * a,
		x.y * (1.0f - a) + y.y * a,
	};
}

Inline S_RGBA8UI mix(const S_RGBA8UI& x, const S_RGBA8UI& y, const float32 a) {
	return { 
		uint8(x.r * (1 - a) + y.r * a),
		uint8(x.g * (1 - a) + y.g * a),
		uint8(x.b * (1 - a) + y.b * a),
		uint8(x.a * (1 - a) + y.a * a),
	};
}


Inline float min(float32 a, float32 b) {
	return (b < a) ? b : a;
}

Inline uint32 min_u32(uint32 a, uint32 b) {
	return (b < a) ? b : a;
}
Inline uint32 max_u32(uint32 a, uint32 b) {
	return (b >= a) ? b : a;
}


Inline vec2 min(const vec2& x, const vec2& y) {
	return { (x.x < y.x) ? x.x : y.x ,
			 (x.y < y.y) ? x.y : y.y
	};
}

Inline vec2 max(const vec2& x, const vec2& y) {
	return { (x.x >= y.x) ? x.x : y.x ,
			 (x.y >= y.y) ? x.y : y.y
	};
}

Inline vec3 mix(const vec3& x, const vec3& y, const float a) {
	return { x.x * (1.0f - a) + y.x * a,
			 x.y * (1.0f - a) + y.y * a,
			 x.z * (1.0f - a) + y.z * a,
	};
}

Inline vec3 min(const vec3& x, const vec3& y) {
	return { (x.x < y.x) ? x.x : y.x ,
			 (x.y < y.y) ? x.y : y.y,
			 (x.z < y.z) ? x.z : y.z
	};
}

Inline vec4 min(const vec4& a, const vec4& b) {
	return { min(a.x, b.x),
			 min(a.y, b.y),
			 min(a.z, b.z),
			 min(a.w, b.w),
	};
}

Inline float max(float32 a, float32 b) {
	return (a > b) ? a : b;
}

Inline vec3 max(const vec3& x, const vec3& y) {
	return { (x.x > y.x) ? x.x : y.x ,
			 (x.y > y.y) ? x.y : y.y,
			 (x.z > y.z) ? x.z : y.z
	};
}

Inline vec4 max(const vec4& x, const vec4& y) {
	return { (x.x > y.x) ? x.x : y.x ,
			 (x.y > y.y) ? x.y : y.y ,
			 (x.z > y.z) ? x.z : y.z ,
			 (x.w > y.w) ? x.w : y.w ,
	};
}


Inline ivec2 min(const ivec2& x, const ivec2& y) {
	return { 
		(x.x < y.x) ? x.x : y.x ,
		(x.y < y.y) ? x.y : y.y ,
	};
}
Inline ivec2 max(const ivec2& x, const ivec2& y) {
	return { 
		(x.x > y.x) ? x.x : y.x ,
		(x.y > y.y) ? x.y : y.y ,
	};
}





Inline float32 length(const vec2& vec) {
	return sqrt(fabs((vec.x * vec.x) + (vec.y * vec.y)));
}

Inline float32 length(const vec3& vec) {
	return sqrt(fabs((vec.x * vec.x) + (vec.y * vec.y) + (vec.z * vec.z)));
}


Inline float dot(const vec4& vec0, const vec4& vec1) {
	return vec0.x * vec1.x + vec0.y * vec1.y + vec0.z * vec1.z + vec0.w * vec1.w;
}


Inline float32 cross1D(const vec2& p0, const vec2& p1) {
	return (p1.x - p0.x) * (p1.y + p0.y);
}
Inline float32 cross(const vec2& o, const vec2& a, const vec2& b) {
	return (a.x-o.x)*(b.y-o.y) - (a.y-o.y)*(b.x-o.x);
}

Inline float32 vec_normal(vec2& vec){
	float32 len = length(vec);
	vec /= len; 
	return len;
}

Inline float32 vec_disSquar(vec2 p0, const vec2& p1) {
	p0 -= p1;
	return p0.x*p0.x + p0.y*p0.y;
}



typedef struct {
	vec3 dir;
	float32 w;
}S_Quat;



//=============================================== 矩阵 ====================================================
typedef struct {
	vec2 m0, m1;
}mat2;

typedef struct {
	vec2 m0, m1, m2, m3;
}mat2x4;

typedef struct {
	vec3	row0;
	vec3	row1;
	vec3	row2;
}mat3X3;
typedef mat3X3 mat3;

typedef struct {
	vec2	row0;
	vec2	row1;
	vec2	row2;
}mat3X2;

typedef struct {
	vec2	row0;
	vec2	row1;
	vec2	row2;
	vec2	row3;
}mat4X2;

typedef struct {
	vec3	row0;
	vec3	row1;
	vec3	row2;
	vec3	row3;
}mat4X3;

typedef struct {
	vec4	row0;
	vec4	row1;
	vec4	row2;
}mat3X4;


//typedef struct {
//	vec4	row0;
//	vec4	row1;
//	vec4	row2;
//	vec4	row3;
//}mat4;
typedef struct _mat4 {
	vec4 m0, m1, m2, m3;
}mat4;



#define _MAT44F					\
typedef struct {				\
	float32 m00, m01, m02, m03, \
			m10, m11, m12, m13, \
			m20, m21, m22, m23, \
			m30, m31, m32, m33; \
}Mat44f;						
_MAT44F;



typedef struct {
	vec2   min;
	vec2   max;
}S_Bounding2D;





//=============================================== 颜色 ==================================================

inline S_RGBA8UI operator + (const S_RGBA8UI& a, const S_RGBA8UI& b) {
	S_RGBA8UI Color;
	Color.r = DEF_Min(a.r + b.r, 255);
	Color.g = DEF_Min(a.g + b.g, 255);
	Color.b = DEF_Min(a.b + b.b, 255);
	Color.a = DEF_Min(a.a + b.a, 255);
	return Color;
}

inline S_RGBA8UI operator + (const S_RGBA8UI& a, const uint8& b) {
	S_RGBA8UI Color;
	Color.r = DEF_Min(a.r + b, 255);
	Color.g = DEF_Min(a.g + b, 255);
	Color.b = DEF_Min(a.b + b, 255);
	Color.a = DEF_Min(a.a + b, 255);
	return Color;
}


inline S_RGBA8UI operator - (const S_RGBA8UI& a, const S_RGBA8UI& b) {
	S_RGBA8UI Color;
	Color.r = DEF_Min(a.r - b.r, 255);
	Color.g = DEF_Min(a.g - b.g, 255);
	Color.b = DEF_Min(a.b - b.b, 255);
	Color.a = DEF_Min(a.a - b.a, 255);
	return Color;
}
inline S_RGBA8UI operator - (const S_RGBA8UI& a, const uint8& b) {
	S_RGBA8UI Color;
	Color.r = DEF_Min(a.r - b, 255);
	Color.g = DEF_Min(a.g - b, 255);
	Color.b = DEF_Min(a.b - b, 255);
	Color.a = DEF_Min(a.a - b, 255);
	return Color;
}
inline S_RGBA8UI operator * (const S_RGBA8UI& a, float32 b) {
	S_RGBA8UI Color;
	Color.r = DEF_Min(float32(a.r) * b, 255);
	Color.g = DEF_Min(float32(a.g) * b, 255);
	Color.b = DEF_Min(float32(a.b) * b, 255);
	Color.a = DEF_Min(float32(a.a) * b, 255);
	return Color;
}
inline S_RGBA8UI operator * (const S_RGBA8UI& a, vec4 b) {
	S_RGBA8UI Color;
	Color.r = DEF_Min(float32(a.r) * b.x, 255);
	Color.g = DEF_Min(float32(a.g) * b.y, 255);
	Color.b = DEF_Min(float32(a.b) * b.z, 255);
	Color.a = DEF_Min(float32(a.a) * b.w, 255);
	return Color;
}


inline void operator += (S_RGBA8UI& a, const uint32 b) {
	a.r = DEF_Min(a.r + b, 255);
	a.g = DEF_Min(a.g + b, 255);
	a.b = DEF_Min(a.b + b, 255);
	a.a = DEF_Min(a.a + b, 255);
}

inline void operator += (S_RGBA8UI& a, const S_RGBA8UI& b) {
	a.r = DEF_Min(a.r + b.r, 255);
	a.g = DEF_Min(a.g + b.g, 255);
	a.b = DEF_Min(a.b + b.b, 255);
	a.a = DEF_Min(a.a + b.a, 255);
}

inline void operator -= (S_RGBA8UI& a, const S_RGBA8UI& b) {
	a.r = DEF_Max(a.r - b.r, 0);
	a.g = DEF_Max(a.g - b.g, 0);
	a.b = DEF_Max(a.b - b.b, 0);
	a.a = DEF_Max(a.a - b.a, 0);
}

inline vec4 f_RGBA(S_RGBA8UI& color) {
	return {
		color.r / 255.0f,
		color.g / 255.0f,
		color.b / 255.0f,
		color.a / 255.0f,
	};
}
inline vec3 f_RGB(S_RGBA8UI& color) {
	return {
		color.r / 255.0f,
		color.g / 255.0f,
		color.b / 255.0f,
	};
}


inline void operator == (S_RGBA8UI& a, const S_RGB8UI& b) {
	
}



Inline uint32 f_col_v4_to_u32(const vec4& color) {
	vec4 c = min(color, {1,1,1}) * 255;
	return (uint32(c.x) << 24 | (uint32(c.y) << 16) | (uint32(c.z) << 8) | uint32(c.w));
}

Inline uint32 f_col_v3_to_u32(const vec3& color) {
	vec3 c = min(color, { 1,1,1 }) * 255;
	return (uint32(c.x) << 24 | (uint32(c.y) << 16) | (uint32(c.z) << 8) | uint32(255));
}

Inline S_RGBA8UI f_col_v4_to_u8(const vec4& color) {
	vec4 c = min(color, { 1,1,1 }) * 255;
	return S_RGBA8UI{uint8(c.x), uint8(c.y), uint8(c.z), uint8(c.w)};
}
Inline S_RGBA8UI f_col_v3_to_u8(const vec3& color) {
	vec3 c = min(color, { 1,1,1 }) * 255;
	return S_RGBA8UI{ uint8(c.x), uint8(c.y), uint8(c.z), 255 };
}




typedef struct {
	float32    x;
	float32    y;
	float32    width;
	float32    height;
	float32    minDepth;
	float32    maxDepth;
} S_Viewport;







//=================================================== 数组 ===================================================

//typedef struct {        
//	bool*  ptr_userData; 
//	uint32 count;  
//}S_BoolArray;	
//
//typedef struct {        
//	int8*  ptr_userData; 
//	uint32 count;  
//}S_I8Array;	

//typedef struct {			
//	float32* ptr_userData;	
//	uint32   count;		
//}S_F32Array;		
//
//typedef struct {			
//	int32*	ptr_userData;	
//	uint32	count;		    
//}S_I32Array;	
//
//typedef struct {			
//	uint32*	ptr_userData;	
//	uint32	count;		    
//}S_UI32Array;	

//typedef struct {
//	S_UI32Array** ptr_userData;
//	uint32	count;
//}S_UI32Array2D;

//typedef struct {			
//	vec2*	ptr_userData;	
//	uint32	count;			
//}S_Vec2Array;
//
//typedef struct {		
//	vec3*  ptr_userData;	
//	uint32 count;		
//}S_Vec3Array;
//
//typedef struct {		
//	vec4*  ptr_userData;	
//	uint32 count;		
//}S_Vec4Array;
//
//typedef struct {			
//	ivec2*	ptr_userData;	
//	uint32	count;			
//}S_iVec2Array;
//
//typedef struct {			
//	uvec2*	ptr_userData;	
//	uint32	count;			
//}S_uVec2Array;
//
//typedef struct {			
//	ivec3*	ptr_userData;	
//	uint32	count;			
//}S_iVec3Array;
//
//typedef struct {			
//	mat3X3* ptr_userData;	
//	uint32	count;			
//}S_Mat33Array;
//
//typedef struct {			
//	Mat44f* ptr_userData;	
//	uint32	count;			
//}S_Mat44Array;



/*template<typename T1, typename T2>
Inline void f_JIT_Fun_fs_c_fs(float32* r, T1* v1, T2* v2, uint32 size[2], uint8 CalType) {
	uint32 num = size[0];
	bool single = size[1] < num;

	for (uint32 i = 0; i < num; ++i) {
		if (single) {
			switch (CalType) {
			case 0: r[i] = float32(v1[i]) + float32(v2[0]); break;
			case 1: r[i] = float32(v1[i]) - float32(v2[0]); break;
			case 2: r[i] = float32(v1[i]) * float32(v2[0]); break;
			case 3: r[i] = float32(v1[i]) / float32(v2[0]); break;
			
			}
		}
		else {
			switch (CalType) {
			case 0: r[i] = float32(v1[i]) + float32(v2[i]); break;
			case 1: r[i] = float32(v1[i]) - float32(v2[i]); break;
			case 2: r[i] = float32(v1[i]) * float32(v2[i]); break;
			case 3: r[i] = float32(v1[i]) / float32(v2[i]); break;

			}
		}
	}
}*/


template<typename T1>
Inline void f_JIT_Fun_Clamp(float32* r, T1* v1, uint32 num, vec2 range) {
	for (uint32 i = 0; i < num; ++i) {
		r[i] = DEF_Min(DEF_Max(range.x, v1[i]), range.y);
	}
}


//Inline vec3 clamp(vec3 x, vec3 minVal, vec3 maxVal) {
//	return { DEF_Min(DEF_Max(x.x, minVal.x), maxVal.x), DEF_Min(DEF_Max(x.y, minVal.y), maxVal.y), DEF_Min(DEF_Max(x.z, minVal.z), maxVal.z) };
//}

CORE_ARRAY_HANDLE(S_BoolArray, bool);
CORE_ARRAY_HANDLE(S_I8Array, int8);
CORE_ARRAY_HANDLE(S_UI8Array, uint8);
CORE_ARRAY_HANDLE(S_F32Array, float32);
CORE_ARRAY_HANDLE(S_I32Array, int32);
CORE_ARRAY_HANDLE(S_UI32Array, uint32);
CORE_ARRAY_HANDLE(S_Vec2Array, vec2);
CORE_ARRAY_HANDLE(S_Vec3Array, vec3);
CORE_ARRAY_HANDLE(S_Vec4Array, vec4);
CORE_ARRAY_HANDLE(S_iVec2Array, ivec2);
CORE_ARRAY_HANDLE(S_uVec2Array, uvec2);
CORE_ARRAY_HANDLE(S_iVec3Array, ivec3);
CORE_ARRAY_HANDLE(S_Mat33Array, mat3X3);
CORE_ARRAY_HANDLE(S_Mat44Array, Mat44f);


CORE_ARRAY_HANDLE(S_UI32Array2D, S_UI32Array*)
CORE_ARRAY_HANDLE(S_Vec3Array2D, S_Vec3Array*)
CORE_ARRAY_HANDLE(S_iVec3Array2D, S_iVec3Array*)
CORE_ARRAY_HANDLE(S_iVec4Array, ivec4)

CORE_ARRAY_HANDLE(S_CubeArray, S_Cube)

CORE_ARRAY_HANDLE(S_TexArray, struct S_纹理*)
CORE_ARRAY_HANDLE(S_OBArray, struct S_物体*)
CORE_ARRAY_HANDLE(S_PhyGeomArray, struct S_物理几何体*)
CORE_ARRAY_HANDLE(S_PhyBodyArray, struct S_物理体*)
CORE_ARRAY_HANDLE(S_PhyMaterialArray, struct S_物理材质*)
CORE_ARRAY_HANDLE(S_模型元素索引Array, uint32)

CORE_ARRAY_HANDLE(S_Array, uint8)
CORE_ARRAY_HANDLE(S_1DArray, S_Array*)

//CORE_ARRAY_FUNC()

CORE_ARRAY_HANDLE(S_Curve3D, struct S_CurvePoint3D)

typedef struct {
	S_Curve3D m_曲线点;
	S_UI32Array m_点索引;
}S_Curve;

Inline float sign(float v) {
	return v > 0 ? 1 : (v < 0 ? -1 : 0);
}

Inline int32 sign(int32 v) {
	return v > 0 ? 1 : (v < 0 ? -1 : 0);
}






Inline bool f_basic_isBoxContained(vec3 center, vec3 boxLength, vec3 target) {
	vec3 halfLength = boxLength * 0.5f;

	// 确定XYZ轴范围
	double xMin = center.x - halfLength.x;
	double xMax = center.x + halfLength.x;
	double yMin = center.y - halfLength.y;
	double yMax = center.y + halfLength.y;
	double zMin = center.z - halfLength.z;
	double zMax = center.z + halfLength.z;

	return target.x >= xMin && target.x <= xMax &&
		target.y >= yMin && target.y <= yMax && target.z >= zMin && target.z <= zMax;
}




Inline float32 radians(float32 a) {
	return (a * (M_PI/180.0));
}

Inline float32 radtodu(float32 value) {
	return float32(value * (M_PI / 180.0));
}




#endif //INCLUDE_BASIC_VEC


